package org.zn.note.jdk.net;

/**
 * @ClassName BaseNet
 * @Author zn
 * @Date 2019/4/3 7:49
 **/
/*
单机高并发所受的限制(TCP)
1、文件描述符限制：  Linux一切都是文件
        [server and client] 每个链接都要打开1个socket句柄（文件描述符）
       单进程打开文件数量限制：ulimit -n，指定ulimit -n xxxx数量，受用户限制
       用户文件句柄限制：/etc/security/limits.conf
       appuser soft nofile 10240  appuser用户打开文件软限制
       appuser hard nofile 10240  appuser用户打开文件硬限制
       操作系统文件句柄限制：cat /proc/sys/fs/file-max  （测试环境大概160W，是根据硬件自动计算的，可以手工改）
 2、端口数量限制：
        [client] 每个链接占用1个本地端口，65535个(2^16 -1)
        [server] 本地端口就占1个，用四元组标识每个链接，{local ip, local port, remote ip, remote port}
                  local ip/port 不变，remote ip/port 不同，ipv4大概 2^32 * 2^16
 4、内存限制 ：
        （每个socket大概10~20K，其他。。。）
 */
/*
Linux开启网卡混杂模式：ifconfig en0 promisc   （可以抓起任何经过网卡的数据，无论接收还是发出）
Linux抓包原理：网卡接收一个网络报文时，会遍历系统中所有已经注册的网络协议，并交给对应的处理模块尝试解析。
               谁能处理谁处理。抓包工具就是注册了虚拟协议来接收报文。
               一般windows用Wireshark，Linux用 tcpdump然后用 Wireshark看
 */
/*
Unix IO 操作分两步：这两步都是内核态 (这里要理解下什么是内核态，也就是Linux运行程序的原理)
    步骤一：等待IO（比如网络或硬盘），将数据从网络或硬盘复制到内核的某个缓冲区。
    步骤二：从内核缓冲区复制到应用进程缓冲区。
Unix 系统调用：
    无论函数如何实现，都会做切换：“应用进程中运行”--切换-->“内核中运行”--返回-->“应用进程中运行”。
Unix 5种I/O模型
    1、阻塞式：（步骤一阻塞、步骤二阻塞）
        系统调用read，直接阻塞，直到步骤一 + 步骤二完成。
    2、非阻塞式：（步骤一不阻塞、步骤二阻塞）
        将socket设置为非阻塞（fcntl(sockfd, F_SETFL, O_NONBLOCK); ）。
        系统调用read，步骤一不会阻塞，没准备好就直接返回EWOULDBLOCK。
        如果步骤一准备好了，步骤二会阻塞。
        应用进程循环测试内核应答（步骤一），直到返回成功，会大量占用CPU，这个轮询的过程叫 polling。
    3、I/O复用：I/O multiplexing（步骤一阻塞但可监听多个socket、步骤二阻塞）
        系统调用select，阻塞，多个socket(文件操作符)只要有1个完成了步骤一，就会返回。一次也会返回多个准备好步骤一的socket。
        系统调用read，阻塞式取数据（步骤二）。
        (select, poll, epoll 都是多路复用的具体实现，select < poll < epoll 每个版本都是为了解决前一个版本的问题)
        ( 大概是这样的函数形式  select(sockfd组 ....))
        其实前提是要把socket设置为非阻塞的，只不过把原来轮询的工作交给select了。
    4、信号驱动
        设置socket允许信号I/O驱动，然后设置SIGIO处理程序（sigaction），当内核完成步骤一后，会发信号。
        后面就是系统调用read阻塞读。
    5、异步I/O
        系统调用aio_read，通知内核进行异步处理，告诉内核进程缓冲区指针和大小，然后内核异步处理完步骤一和步骤二后发信息号。
    （1~4 的区别只是步骤一，步骤二一样。可以理解为 2~4是步骤一异步处理了。然后 5是让步骤二异步处理了。）
    （如果说 2~4是非阻塞同步IO，也就是说步骤二是同步的，但是步骤一是异步的）
    （是否可以严谨的说 2~4是半异步，5是全异步）
 */
/*
JDK 1.0 实现了阻塞式I/O
JDK 1.4 实现了非阻塞式I/O、以及Selector
JDK 1.7 实现了异步I/O
 */
public class BaseNet {
}
